#ifndef DATABASEMANAGER_H
#define DATABASEMANAGER_H

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QString>

/**
 * @brief 数据库配置命名空间前向声明
 * 包含数据库表名和建表SQL语句的配置
 */
namespace DBTableConfig {
    QStringList getAllTableNames();       ///< 获取所有表名列表
    QString getCreateTableSql(const QString& tableName);  ///< 获取指定表的建表SQL
}

/**
 * @brief 数据库管理类
 * 采用单例模式设计，负责SQLite数据库的连接管理、表结构初始化
 * 以及提供统一的SQL执行接口，确保数据库操作的一致性和安全性
 */
class DatabaseManager
{
public:
    /**
     * @brief 获取单例实例
     * 确保全局只有一个DatabaseManager对象
     * @return DatabaseManager* 单例对象指针
     */
    static DatabaseManager* getInstance();

    /**
     * @brief 析构函数
     * 关闭数据库连接并释放资源
     */
    ~DatabaseManager();

    /**
     * @brief 打开数据库连接
     * 初始化SQLite数据库连接，若连接已存在则先关闭再重新连接
     * @param dbName 数据库文件名（支持相对路径和绝对路径）
     * @return bool 连接成功返回true，否则返回false
     */
    bool openDatabase(const QString& dbName);

    /**
     * @brief 关闭数据库连接
     * 安全关闭当前数据库连接，释放相关资源
     */
    void closeDatabase();

    /**
     * @brief 获取数据库连接对象
     * 提供原始QSqlDatabase对象供外部使用（谨慎操作）
     * @return QSqlDatabase 数据库连接对象
     */
    QSqlDatabase getDatabase() const;

    /**
     * @brief 检查数据库连接状态
     * @return bool 连接有效且已打开返回true，否则返回false
     */
    bool isConnected() const;

    /**
     * @brief 执行SQL语句（无返回结果）
     * 用于执行INSERT/UPDATE/DELETE等不需要返回结果的SQL语句
     * @param sql 待执行的SQL语句
     * @param errorMsg 输出参数，用于存储错误信息
     * @return bool 执行成功返回true，否则返回false
     */
    bool executeSql(const QString& sql, QString* errorMsg = nullptr);

    /**
     * @brief 执行查询SQL语句（带返回结果）
     * 用于执行SELECT等需要返回结果集的SQL语句
     * @param sql 待执行的查询SQL语句
     * @param errorMsg 输出参数，用于存储错误信息
     * @return QSqlQuery 查询结果对象，需检查有效性后使用
     */
    QSqlQuery executeQuery(const QString& sql, QString* errorMsg = nullptr);

    /**
     * @brief 检查并创建所有数据表
     * 批量检查所有配置的表是否存在，不存在则创建
     * @param errorMsg 输出参数，用于存储累积的错误信息
     * @return bool 所有表都检查/创建成功返回true，否则返回false
     */
    bool checkAndCreateAllTables(QString* errorMsg = nullptr);

    /**
     * @brief 检查指定表是否存在
     * 查询SQLite系统表判断表是否已创建
     * @param tableName 表名
     * @return bool 表存在返回true，否则返回false
     */
    bool isTableExists(const QString& tableName);

    /**
     * @brief 若表不存在则创建
     * 先检查表是否存在，不存在则使用配置的SQL语句创建
     * @param tableName 表名
     * @param errorMsg 输出参数，用于存储错误信息
     * @return bool 表已存在或创建成功返回true，否则返回false
     */
    bool createTableIfNotExists(const QString& tableName, QString* errorMsg = nullptr);

private:
    /**
     * @brief 私有构造函数
     * 单例模式防止外部实例化，初始化成员变量
     */
    DatabaseManager();

    static DatabaseManager* instance;  ///< 单例实例指针
    QSqlDatabase db;                   ///< 数据库连接对象
    bool connected;                    ///< 连接状态标志

    // 禁止拷贝构造和赋值操作
    DatabaseManager(const DatabaseManager&) = delete;
    DatabaseManager& operator=(const DatabaseManager&) = delete;
};

#endif // DATABASEMANAGER_H
